package com.qyer.util.log.service.impl;

import java.lang.reflect.InvocationTargetException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.phprpc.util.PHPSerializer;

import com.qyer.util.log.common.Constants;
import com.qyer.util.log.entity.AppLogInfo;
import com.qyer.util.log.entity.AppTrackLog;
import com.qyer.util.log.entity.ArsalNginxLog;
import com.qyer.util.log.entity.NginxLog;
import com.qyer.util.log.util.AppLogUtil;
import com.qyer.util.log.util.JsonUtils;
import com.qyer.util.log.util.MyDateUtil;


/** 
* 此类描述的是： AppTrackServiceImpl接口实现类
* @author: hongxi.sun@qyer.com 
* @version: 2015年9月21日 上午10:00:24 
*/
public class AppTrackV2ServiceImpl {
	/** 
	* 此方法描述的是： 清洗 track nginxlog
	* @author: hongxi.sun@qyer.com 
	* @version: 2015年9月21日 上午10:00:24 
	* @param  String line 
	* @return  TrackLog  格式有问题时返回 null
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	*/
	public AppTrackLog getTrack4NginxFormat(String line) throws Exception {
		NginxLog nginxLog = AppLogUtil.getNginxLog(line);
		if (nginxLog == null) {
			return null;
		}
		AppTrackLog trackLog = new AppTrackLog();
		if(!initBaseLog(nginxLog,trackLog)){
			return null ;
		}
		
		if(trackLog.getDeviceid()==null){
			return null ; 
		}
		
		Map<String, String> urlParamMaps = trackLog.getParamsMap();
		if (urlParamMaps == null||urlParamMaps.size()==0) {
			return null;
		}
		
		Map<String, String> extParamMaps = trackLog.getParamsMap();
		extParamMaps.remove("track_user_id");
		extParamMaps.remove("lat");
		extParamMaps.remove("lon");
		extParamMaps.remove("track_app_version");
		extParamMaps.remove("installtime");
		
		extParamMaps.remove("info");
		extParamMaps.remove("track_device_info");
		extParamMaps.remove("ip");
		extParamMaps.remove("client_secret");
		extParamMaps.remove("track_app_channel");
		extParamMaps.remove("track_os");
		extParamMaps.remove("client_id");
		extParamMaps.remove("track_deviceid");
		
		extParamMaps.remove("api_name");
		extParamMaps.remove("oauth_token");
		extParamMaps.remove("timestamp");
		//extParamMaps.remove("timestamp");
		trackLog.setExtParamMap(extParamMaps);
		
		return trackLog;
	}
	
	/** 
	* 此方法描述的是： 清洗 track nginxlog
	* @author: hongxi.sun@qyer.com 
	* @version: 2015年9月21日 上午10:00:24 
	* @param  String line 
	* @return  TrackLog  格式有问题时返回 null
	*/
	public AppTrackLog getArsal4NginxFormat(String line) {
		ArsalNginxLog nginxLog = AppLogUtil.getArsalNginxLog(line);
		if (nginxLog == null) {
			return null;
		}
		AppTrackLog trackLog = new AppTrackLog();
//		if(!AppLogUtil.initBaseLog(nginxLog,trackLog)){
//			return null ;
//		}
		
		if(trackLog.getDeviceid()==null){
			return null ; 
		}
		
		Map<String, String> urlParamMaps = trackLog.getParamsMap();
		if (urlParamMaps == null||urlParamMaps.size()==0) {
			return null;
		}
		
		Map<String, String> extParamMaps = trackLog.getParamsMap();
		extParamMaps.remove("track_user_id");
		extParamMaps.remove("lat");
		extParamMaps.remove("lon");
		extParamMaps.remove("track_app_version");
		extParamMaps.remove("installtime");
		
		extParamMaps.remove("info");
		extParamMaps.remove("track_device_info");
		extParamMaps.remove("ip");
		extParamMaps.remove("client_secret");
		extParamMaps.remove("track_app_channel");
		extParamMaps.remove("track_os");
		extParamMaps.remove("client_id");
		extParamMaps.remove("track_deviceid");
		
		extParamMaps.remove("api_name");
		extParamMaps.remove("oauth_token");
		extParamMaps.remove("timestamp");
		//extParamMaps.remove("timestamp");
		trackLog.setExtParamMap(extParamMaps);
		
		return trackLog;
	}

	/** 
	* 此方法描述的是： 清洗 tracklog 初始化  UGC 相关的数据  页面类型 频道  以及ugc_contents
	* @author: hongxi.sun@qyer.com 
	* @version: 2015年9月08日 上午10:00:24 
	* @param  TrackLog trackLog 
	* @return  String  格式有问题时返回 null
	*/
	public AppTrackLog setCurlUGC(AppTrackLog trackLog  ,Map <String , String> pagetypeMaps ,  
				Map <String , String> channelMaps , Map <String , String> cityMaps , Map <String, String > countryMaps) {
		
		return trackLog;
	}
	
	/**
	 * 正则匹配获取匹配的内容
	 * 
	 * @param regex
	 * @param url
	 * @return
	 */
	public boolean getRegExBool(String regex, String url) {
		boolean result = false;
		Pattern pat = Pattern.compile(regex);
		Matcher mat = pat.matcher(url);
		while (mat.find()) {
			result = true;
		}
		return result;
	}
	
	/**
	 * 正则匹配获取匹配的内容
	 * 
	 * @param regex
	 * @param url
	 * @return
	 */
	public String getRegEx(String regex, String url) {
		String result = "-,-";
		Pattern pat = Pattern.compile(regex);
		Matcher mat = pat.matcher(url);
		while (mat.find()) {
			if (mat.groupCount() > 0) {
				if (null != mat.group(1)) {
					result = mat.group(1);
				}
			}

		}
		return result;
	}

	/** 
	* 此方法描述的是： 针对清洗日志获取对象
	* @author: hongxi.sun@qyer.com 
	* @version: 2015年9月08日 上午10:00:24 
	* @param  String line 
	* @return  TrackLog  格式有问题时返回 null
	*/
	public AppTrackLog getTrackFormat(String strLine) {
		
		if (strLine == null || strLine.equals("")) {
			return null;
		}
		
		String [] ls = StringUtils.split(strLine , Constants.FS);
		
		if(ls .length<20){
			return null; 
		}

		AppTrackLog tracklog = new AppTrackLog();
		
		String timestamp =MyDateUtil.toTimeStamp2(tracklog.getTrackTime());
		tracklog.setTimeStamp(timestamp);
		
		return tracklog ;
	}
	

	/**
	 * 此方法描述的是：初始化 日志父类
	 * @param strLine  一行原始Nginx日志
	 * @author: hongxi.sun@qyer.com
	 * @version: 2015年8月29日 下午3:23:38
	 * @return 是否成功
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 */
	public static Boolean initBaseLog(NginxLog nginxLog, AppTrackLog trackLog) throws Exception {
		
		if (nginxLog == null) {
			return false;
		}

		if (nginxLog.getRequest().indexOf("POST ") > -1&& nginxLog.getRequest().indexOf("HTTP/") > -1){
			String requestParam = nginxLog.getRequest().substring(nginxLog.getRequest().indexOf("POST ") + 5,nginxLog.getRequest().indexOf(" HTTP/"));
			trackLog.setType(requestParam);

			String requestbody= nginxLog.getRequest_body();
			trackLog.getParamsMap().putAll(AppLogUtil.requestParamUrlToMap(requestbody));
		}else{
			return false;
		}
		
		trackLog.setApiPath((preProcess(nginxLog.getRequest(), "utf-8")));
		trackLog.setUserIp(nginxLog.getRemote_addr());
		trackLog.setUserAgent(nginxLog.getHttp_user_agent());
		trackLog.setPlatform("app");
		trackLog.setUserId(trackLog.getParamsMap().get("track_user_id"));
		trackLog.setLon(trackLog.getParamsMap().get("lon"));
		trackLog.setLat(trackLog.getParamsMap().get("lat"));
		trackLog.setAppVersion(trackLog.getParamsMap().get("track_app_version"));
		trackLog.setInstalltime(trackLog.getParamsMap().get("installtime"));
		trackLog.setInfo(trackLog.getParamsMap().get("info"));
		trackLog.setDeviceInfo(trackLog.getParamsMap().get("track_device_info"));
		trackLog.setUserIp(trackLog.getParamsMap().get("ip"));
		trackLog.setClientSecret(trackLog.getParamsMap().get("client_secret"));
		trackLog.setAppChannel(trackLog.getParamsMap().get("track_app_channel"));
		trackLog.setOs(trackLog.getParamsMap().get("track_os"));
		trackLog.setClientId(trackLog.getParamsMap().get("client_id"));
		trackLog.setDeviceid(trackLog.getParamsMap().get("track_deviceid"));
		trackLog.setApiName(trackLog.getParamsMap().get("api_name"));
		trackLog.setAuthToken(trackLog.getParamsMap().get("oauth_token"));
		trackLog.setDeviceName(trackLog.getParamsMap().get("device_name"));
		
		//url map
		if(trackLog.getParamsMap().containsKey("timestamp")){
			Long ts = Long.parseLong(trackLog.getParamsMap().get("timestamp"));
			ts=ts*1000; 
			trackLog.setTimeStamp(ts.toString());
		}
		
		if(trackLog.getInfo()!=null &&!"".equals(trackLog.getInfo())){
			try {
				Map <String, String> infoMaps =JsonUtils.toJavaBean(trackLog.getInfo(), Map.class);
				if(infoMaps.get("ra_n_model")!=null){
					trackLog.setRa_n_model(infoMaps.get("ra_n_model").toString());
					infoMaps.remove("ra_n_model");
				}
				if(infoMaps.get("ra_n_page")!=null){
					trackLog.setRa_n_page(infoMaps.get("ra_n_page").toString());
					infoMaps.remove("ra_n_page");
				}
				if(infoMaps.get("ra_n_referer")!=null){
					trackLog.setRa_n_referer(infoMaps.get("ra_n_referer").toString());
					infoMaps.remove("ra_n_referer");
				}
				if(infoMaps.get("params")!=null){
					trackLog.setParams(infoMaps.get("params").toString());
					infoMaps.remove("params");
				}
				
				trackLog.setInfoMaps(infoMaps);
			} catch (Exception e) {
				try {
					PHPSerializer p = new PHPSerializer();
					
					AppLogInfo t =  (AppLogInfo) p.unserialize(trackLog.getInfo().getBytes(),AppLogInfo.class);
					if(t!=null){
						trackLog.setRa_n_model(t.getRa_n_model());
					    trackLog.setRa_n_page(t.getRa_n_page());
					    trackLog.setRa_n_referer(t.getRa_n_referer());
					    trackLog.setParams(t.getParams());
					}
				} catch (Exception e1) {
					
				}
			}
		}
		
		return true;
	}
	
	/**
	 * 此方法描述的是：URL  decode
	 * @param strLine  一行原始Nginx日志
	 * @author: hongxi.sun@qyer.com
	 * @version: 2015年8月29日 下午3:23:38
	 * @return String
	 */
	private static String preProcess(String strSources, String strCode) {
		if (!strCode.isEmpty()) {
			try {
				strSources = URLDecoder.decode(strSources, strCode);
				strSources=strSources.replace("\001", "");
				strSources=strSources.replace("\002", "");
				strSources=strSources.replace("\003", "");
				strSources=strSources.replace("\004", "");
				strSources=strSources.replace("\005", "");
				strSources=strSources.replace("\006", "");
				strSources=strSources.replace("\n", "");
				strSources=strSources.replace("\r", "");
			} catch (Exception e) {
				return "";
			}
		}
		return strSources;
	}
}
